// tradingUtils.js - 存放交易相关的工具函数

/**
 * 下载文件工具函数
 * @param {string} content - 文件内容
 * @param {string} filename - 文件名
 * @param {string} mimeType - MIME类型
 */
export const downloadFile = (content, filename, mimeType = 'text/plain') => {
  try {
    // 创建 Blob 对象
    const blob = new Blob([content], { type: mimeType })
    
    // 创建下载链接
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = filename
    
    // 临时添加到 DOM 并触发下载
    document.body.appendChild(link)
    link.click()
    
    // 清理资源
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    console.log(`📁 文件下载成功: ${filename}`)
  } catch (error) {
    console.error('📁 文件下载失败:', error)
    throw new Error(`文件下载失败: ${error.message}`)
  }
}

/**
 * 生成CSV数据
 * @param {Array} trades - 交易数据
 * @returns {string} CSV格式的字符串
 */
export const generateCSV = (trades) => {
  const headers = [
    '交易ID', '日期', '时间', '类型', '价格', '数量', '价值', '盈亏', '原因', '实时数据'
  ]
  
  const csvRows = [
    headers.join(',')
  ]
  
  trades.forEach(trade => {
    const row = [
      trade.id,
      trade.date,
      trade.time,
      trade.type === 'buy' ? '买入' : '卖出',
      trade.price.toFixed(2),
      trade.amount.toFixed(6),
      trade.value.toFixed(2),
      (trade.profit || 0).toFixed(2),
      `"${trade.reason}"`, // 用引号包裹以防止CSV格式问题
      trade.isRealTime ? '是' : '否'
    ]
    csvRows.push(row.join(','))
  })
  
  return csvRows.join('\n')
}

/**
 * 计算虚拟交易统计数据
 * @param {Object} virtualTradingResults - 虚拟交易结果
 * @param {Object} backtestSettings - 回测设置
 * @returns {Object} 统计数据
 */
export const calculateVirtualTradingStatistics = (virtualTradingResults, backtestSettings) => {
  const trades = virtualTradingResults.trades
  if (!trades || trades.length === 0) {
    return {
      totalTrades: 0,
      winningTrades: 0,
      losingTrades: 0,
      winRate: 0,
      averageWin: 0,
      averageLoss: 0,
      profitFactor: 0,
      maxWin: 0,
      maxLoss: 0,
      maxDrawdown: 0,
      maxDrawdownPercent: 0,
      sharpeRatio: 0,
      totalReturn: virtualTradingResults.pnlPercent,
      tradingDays: 0
    }
  }
  
  // 基本统计
  const totalTrades = trades.length
  const sellTrades = trades.filter(t => t.type === 'sell' && t.profit !== undefined)
  const winningTrades = sellTrades.filter(t => t.profit > 0)
  const losingTrades = sellTrades.filter(t => t.profit < 0)
  
  const winRate = sellTrades.length > 0 ? (winningTrades.length / sellTrades.length) * 100 : 0
  
  // 盈亏统计
  const totalWin = winningTrades.reduce((sum, t) => sum + t.profit, 0)
  const totalLoss = Math.abs(losingTrades.reduce((sum, t) => sum + t.profit, 0))
  const averageWin = winningTrades.length > 0 ? totalWin / winningTrades.length : 0
  const averageLoss = losingTrades.length > 0 ? totalLoss / losingTrades.length : 0
  const profitFactor = totalLoss > 0 ? totalWin / totalLoss : totalWin > 0 ? Infinity : 0
  
  const maxWin = winningTrades.length > 0 ? Math.max(...winningTrades.map(t => t.profit)) : 0
  const maxLoss = losingTrades.length > 0 ? Math.min(...losingTrades.map(t => t.profit)) : 0
  
  // 计算最大回撤
  let maxDrawdown = 0
  let maxDrawdownPercent = 0
  let peak = backtestSettings.initialCapital
  let currentCapital = backtestSettings.initialCapital
  
  trades.forEach(trade => {
    if (trade.type === 'sell' && trade.profit !== undefined) {
      currentCapital += trade.profit
      if (currentCapital > peak) {
        peak = currentCapital
      } else {
        const drawdown = peak - currentCapital
        const drawdownPercent = (drawdown / peak) * 100
        if (drawdown > maxDrawdown) {
          maxDrawdown = drawdown
          maxDrawdownPercent = drawdownPercent
        }
      }
    }
  })
  
  // 计算交易天数
  const tradeDates = [...new Set(trades.map(t => t.date))]
  const tradingDays = tradeDates.length
  
  // 简化的夏普比率计算（假设无风险收益率3%）
  const riskFreeRate = 0.03
  const annualReturn = tradingDays > 0 ? (virtualTradingResults.pnlPercent / 100) * (365 / tradingDays) : 0
  const volatility = sellTrades.length > 1 ? 
    Math.sqrt(sellTrades.reduce((sum, t) => {
      const returnRate = t.profit / backtestSettings.initialCapital
      const avgReturn = (virtualTradingResults.pnl / backtestSettings.initialCapital) / sellTrades.length
      return sum + Math.pow(returnRate - avgReturn, 2)
    }, 0) / (sellTrades.length - 1)) * Math.sqrt(365) : 0
  
  const sharpeRatio = volatility > 0 ? (annualReturn - riskFreeRate) / volatility : 0
  
  return {
    totalTrades,
    winningTrades: winningTrades.length,
    losingTrades: losingTrades.length,
    winRate: parseFloat(winRate.toFixed(2)),
    averageWin: parseFloat(averageWin.toFixed(2)),
    averageLoss: parseFloat(averageLoss.toFixed(2)),
    profitFactor: parseFloat(profitFactor.toFixed(2)),
    maxWin: parseFloat(maxWin.toFixed(2)),
    maxLoss: parseFloat(maxLoss.toFixed(2)),
    maxDrawdown: parseFloat(maxDrawdown.toFixed(2)),
    maxDrawdownPercent: parseFloat(maxDrawdownPercent.toFixed(2)),
    sharpeRatio: parseFloat(sharpeRatio.toFixed(3)),
    totalReturn: parseFloat(virtualTradingResults.pnlPercent.toFixed(2)),
    tradingDays
  }
}

/**
 * 计算价格差异
 * @param {Object} item - 比较数据项
 * @returns {number} 价格差异百分比
 */
export const calculatePriceDiff = (item) => {
  const prices = [
    parseFloat(item.coingecko.price.replace(/,/g, '')) || 0,
    parseFloat(item.binance.price.replace(/,/g, '')) || 0,
    parseFloat(item.cryptocompare.price.replace(/,/g, '')) || 0
  ].filter(price => price > 0)
  
  if (prices.length < 2) {
    return 0
  }
  
  const maxPrice = Math.max(...prices)
  const minPrice = Math.min(...prices)
  return ((maxPrice - minPrice) / minPrice) * 100
}

/**
 * 生成模拟K线数据
 * @param {number} basePrice - 基础价格
 * @returns {Array} K线数据
 */
export const generateKLineData = (basePrice) => {
  const data = []
  const today = new Date()
  
  for (let i = 0; i < 100; i++) {
    const date = new Date(today)
    date.setDate(date.getDate() - (100 - i))
    const dateStr = date.toISOString().split('T')[0]
    
    const open = basePrice + Math.random() * 2000 - 1000
    const close = open + Math.random() * 1000 - 500
    const low = Math.min(open, close) - Math.random() * 500
    const high = Math.max(open, close) + Math.random() * 500
    
    data.push([dateStr, open, close, low, high])
  }
  
  return data
}